/**
 * 
 */
function GameEngine() {
	if(GameEngine.instance) return GameEngine.instance; //单例模式
	this.randomNum = [2, 4]; //面板上随机产生的数
	this.dyadic_array = []; //面板对应的二维数组
	this.TABLE_ROW = 4; //行与列
	this.TABLE_COL = 4;
	GameEngine.instance = this;
}
GameEngine.prototype = {
	init: function() {
		//生成面板及对应的二维数组
		this._table = $(".main");
		var frag = document.createDocumentFragment();
		for(var i = 0; i < this.TABLE_ROW; i++) {
			this.dyadic_array[i] = new Array();
			var _tr = document.createElement('tr');
			for(var j = 0; j < this.TABLE_COL; j++) {
				this.dyadic_array[i][j] = 0;
				var _td = document.createElement('td');
				_tr.appendChild(_td);
			}
			frag.appendChild(_tr);
		}
		this._table.appendChild(frag);
		//初始随机三个数
		for(var i = 0; i < 3; i++) {
			var num_site = this.random_Num_Site();
			this.dyadic_array[num_site.Site.x][num_site.Site.y] = num_site.Num;
		}
		//打印二维数组
		this.print();
		//开始游戏
		this.start()
	},
	print: function() {
		for(var i = 0; i < this.TABLE_ROW; i++) {
			for(var j = 0; j < this.TABLE_COL; j++) {
				this._table.children[i].children[j].innerText = ""; //清空页面元素内容及样式
				this._table.children[i].children[j].className = "";
				if(this.dyadic_array[i][j] != 0) {
					this._table.children[i].children[j].innerText = this.dyadic_array[i][j];//根据二维数组内数据更新页面
					this._table.children[i].children[j].className = 'text-' + (this.dyadic_array[i][j] < 9 ? '0-9' : (this.dyadic_array[i][j] < 99 ? '10-99' : this.dyadic_array[i][j] < 999 ? '100-999' : '1000-9999'));
				}
			}
		}
	},
	start: function() { //開始遊戲
		var _this = this;
		this.moveCallback = function(e) {
			e = e || window.event;
			var dir = e.keyCode || e.which;
			switch(dir) {
				case 38: //上
					{
						for(var i = 1; i < this.TABLE_ROW; i++) { //合并0
							for(var j = 0; j < this.TABLE_COL; j++) {
								for(var k = i; k > 0; k--) {
									if(this.dyadic_array[k - 1][j] == 0) {
										this.dyadic_array[k - 1][j] = this.dyadic_array[k][j];
										this.dyadic_array[k][j] = 0;
									}
								}

							}
						}
						for(var i = 1; i < this.TABLE_ROW; i++) { //合并相同值
							for(var j = 0; j < this.TABLE_COL; j++) {
								if(this.dyadic_array[i][j] == this.dyadic_array[i - 1][j] || this.dyadic_array[i - 1][j] == 0) {
									this.dyadic_array[i - 1][j] += this.dyadic_array[i][j];
									this.dyadic_array[i][j] = 0;
									for(var k = i; k < this.TABLE_ROW; k++) {
										this.dyadic_array[k][j] = (k + 1 == this.TABLE_ROW ? 0 : this.dyadic_array[k + 1][j]);
									}
								}

							}
						}
						break;
					}
				case 39: //右
					{
						for(var i = 0; i < this.TABLE_ROW; i++) {
							for(var j = this.TABLE_COL - 2; j >= 0; j--) {
								for(var k = j; k <= this.TABLE_COL - 2; k++) {
									if(this.dyadic_array[i][k + 1] == 0) {
										this.dyadic_array[i][k + 1] = this.dyadic_array[i][k];
										this.dyadic_array[i][k] = 0;
									}
								}

							}
						}
						for(var i = 0; i < this.TABLE_ROW; i++) {
							for(var j = this.TABLE_COL - 2; j >= 0; j--) {
								if(this.dyadic_array[i][j] == this.dyadic_array[i][j + 1]) {
									this.dyadic_array[i][j + 1] *= 2;
									this.dyadic_array[i][j] = 0;
									for(var k = j; k >= 0; k--) {
										this.dyadic_array[i][k] = (k - 1 < 0 ? 0 : this.dyadic_array[i][k - 1]);
									}
								}

							}
						}
						break;
					}
				case 40: //下
					{
						for(var i = this.TABLE_ROW - 2; i >= 0; i--) {
							for(var j = 0; j < this.TABLE_COL; j++) {
								for(var k = i; k < this.TABLE_ROW - 1; k++) {
									if(this.dyadic_array[k + 1][j] == 0) {
										this.dyadic_array[k + 1][j] = this.dyadic_array[k][j];
										this.dyadic_array[k][j] = 0;
									}
								}

							}
						}
						for(var i = this.TABLE_ROW - 2; i >= 0; i--) {
							for(var j = 0; j < this.TABLE_COL; j++) {
								if(this.dyadic_array[i][j] == this.dyadic_array[i + 1][j] || this.dyadic_array[i + 1][j] == 0) {
									this.dyadic_array[i + 1][j] += this.dyadic_array[i][j];
									for(var k = i; k >= 0; k--) {
										this.dyadic_array[k][j] = (k - 1 < 0 ? 0 : this.dyadic_array[k - 1][j]);
									}
								}

							}
						}

						break;
					}
				case 37: //左
					{
						for(var i = 0; i < this.TABLE_ROW; i++) {
							for(var j = 1; j < this.TABLE_COL; j++) {
								for(var k = j; k > 0; k--) {
									if(this.dyadic_array[i][k - 1] == 0) {
										this.dyadic_array[i][k - 1] = this.dyadic_array[i][k];
										this.dyadic_array[i][k] = 0;
									}
								}
							}
						}
						for(var i = 0; i < this.TABLE_ROW; i++) {
							for(var j = 1; j < this.TABLE_COL; j++) {
								if(this.dyadic_array[i][j] == this.dyadic_array[i][j - 1]) {
									this.dyadic_array[i][j - 1] *= 2;
									this.dyadic_array[i][j] = 0;
									for(var k = j; k < this.TABLE_ROW; k++) {
										this.dyadic_array[i][k] = (k + 1 == this.TABLE_COL ? 0 : this.dyadic_array[i][k + 1]);
									}
								}

							}
						}

						break;
					}
			}
			var num_site = this.random_Num_Site();//每次動作后新出現元素
			_this.dyadic_array[num_site.Site.x][num_site.Site.y] = num_site.Num;
			_this.print();//更新頁面
		}.bind(this);
		eventUils.addEvent(document, 'keydown', _this.moveCallback);//添加监听事件

	},
	random_Num_Site: function() {
		var num = this.randomNum[Math.random() > 0.8 ? 1 : 0];//随机出现2或4  ，2的概率为0.8,4的概率为0.2
		var site = null;//将数字随机放入空位
		do {
			site = {
				x: randomUtils.int(3),
				y: randomUtils.int(3)
			}
		} while (this.dyadic_array[site.x][site.y] != 0);
		return {
			Num: num,
			Site: site
		}
	}
}